package org.jeecg.common.util.building_info_util;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import org.jeecg.common.util.list2tree.ListToTreeUtil;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static cn.hutool.core.util.StrUtil.isBlank;

public class BuildingGenerator {
    public static void main(String[] args) {
        List<Building> buildings = generateBuildingList(1, 2, 30, 4);
        System.out.println(JSON.toJSONString(buildings));
    }

    /**
     * @param buildingCount        建立数
     * @param unitCountPerBuilding 每个建筑单元数
     * @param floorCountPerUnit    地板计数单位
     * @param houseCountPerFloor   每层楼房子数 入参
     * @return {@link List }<{@link Building }>
     * @author zjarlin
     * @since 2023/02/20
     */
    public static List<Building> generateBuildingList(int buildingCount, int unitCountPerBuilding, int floorCountPerUnit, int houseCountPerFloor) {
        List<Building> buildings = generateBuildingTree(buildingCount, unitCountPerBuilding, floorCountPerUnit, houseCountPerFloor);
        return ListToTreeUtil.tree2List(buildings, Building::getChildren, Building::setChildren);

    }

    /**
     * 生成建筑树
     *
     * @param buildingCount        楼盘数
     * @param unitCountPerBuilding 每个建筑单元数
     * @param floorCountPerUnit    楼层数
     * @param houseCountPerFloor   每层楼房间数
     * @return {@link List }<{@link Building }>
     * @author zjarlin
     * @since 2023/02/18
     */
    public static List<Building> generateBuildingTree(int buildingCount, int unitCountPerBuilding, int floorCountPerUnit, int houseCountPerFloor) {
        return
            IntStream.rangeClosed(1, buildingCount).mapToObj(buildingId -> {
                    Building building = new Building();
                    building.setId(generateId(buildingId, null, null, null));
                    building.setName(generateName(buildingId, null, null, null));
                    building.setType(1);
                    building.setPid(null);

                    List<Building> units = IntStream.rangeClosed(1, unitCountPerBuilding).mapToObj(unitId -> {
                            Building unit = new Building();
                            unit.setId(generateId(buildingId, unitId, null, null));
                            unit.setName(generateName(buildingId, unitId, null, null));
                            unit.setType(2);
                            unit.setPid(building.getPid());

                            List<Building> floors = IntStream.rangeClosed(1, floorCountPerUnit)
                                .mapToObj(floorId -> {
                                    Building floor = new Building();
                                    floor.setId(generateId(buildingId, unitId, floorId, null));
                                    floor.setName(generateName(buildingId, unitId, floorId, null));
                                    floor.setType(3);
                                    floor.setPid(unit.getId());

                                    List<Building> houses = IntStream.rangeClosed(1, houseCountPerFloor)
                                        .mapToObj(houseId -> {
                                            Building house = new Building();
                                            house.setId(generateId(buildingId, unitId, floorId, houseId));
                                            house.setName(generateName(buildingId, unitId, floorId, houseId));
                                            house.setType(4);
                                            house.setPid(floor.getId());
                                            return house;
                                        })
                                        .collect(Collectors.toList());

                                    floor.setChildren(houses);
                                    return floor;
                                })
                                .collect(Collectors.toList());

                            unit.setChildren(floors);
                            return unit;
                        })
                        .collect(Collectors.toList());

                    building.setChildren(units);
                    return building;
                })
                .collect(Collectors.toList());
    }

    private static String generateId(Integer buildingId, Integer unitId, Integer floor, Integer roomId) {
        StringBuilder sb = new StringBuilder();
        if (Objects.nonNull(buildingId)) {
            // 拼接楼栋编号
            sb.append(String.format("%01d#", buildingId)).append("-");
        }
        if (Objects.nonNull(buildingId)) {
            // 拼接单元编号
            sb.append(unitId).append("-");
        }

        if (Objects.nonNull(buildingId)) {
            // 拼接层数
            sb.append(String.format("%01d", floor)).append("-");
        }

        if (Objects.nonNull(buildingId)) {
            // 拼接房间编号
            sb.append(String.format("%02d", roomId));

        }

        //String s = sb.toString();
        String aNull = StrUtil.removeAny(sb, "-null", "null");
        return removeAnySuffix(aNull, "-");
    }

    public static String generateName(Integer buildingId, Integer unitId, Integer floor, Integer houseId) {
        String name = "";
        if (buildingId != null) {
            name += buildingId + "号楼";
        }
        if (unitId != null) {
            name += unitId + "单元";
        }
        if (floor != null) {
            name += floor + "层";
        }
        if (houseId != null) {
            name += houseId + "室";
        }
        String aNull = StrUtil.removeAny(name, "-null", "null");
        String s = removeAnySuffix(aNull, "-");
        return s;
    }

    private static String removeAnySuffix(String str, final String suffix) {
        if (isBlank(str)) {
            return "";
        }
        while (StrUtil.endWith(str, suffix)) {
            str = StrUtil.removeSuffix(str, suffix);
        }
        return str;
    }

    /**
     * 生成建筑树
     *
     * @param buildingId           楼号
     * @param unitCountPerBuilding 每个建筑单元数
     * @param floorCountPerUnit    楼层数
     * @param houseCountPerFloor   每层楼房间数 入参
     * @return {@link List }<{@link Building }>
     * @author zjarlin
     * @since 2023/02/20
     */
    public static List<Building> generateBuildingOne(int buildingId, int unitCountPerBuilding, int floorCountPerUnit, int houseCountPerFloor) {
        String format = String.format("%01d#", buildingId);
        String format2 = String.format("%01d号楼", buildingId);
        return
            IntStream.rangeClosed(1, 1).mapToObj(x -> {
                        Building building = new Building();
                        building.setId(format);
                        building.setValue(String.valueOf(buildingId));
                        building.setName(format2);
                        building.setType(1);
                        building.setPid(null);

                        List<Building> units = IntStream.rangeClosed(1, unitCountPerBuilding).mapToObj(unitId -> {
                                Building unit = new Building();
                                unit.setId(generateId(buildingId, unitId, null, null));
                                unit.setName(generateName(buildingId, unitId, null, null));
                                unit.setValue(String.valueOf(unitId));
                                unit.setType(2);
                                unit.setPid(building.getPid());

                                List<Building> floors = IntStream.rangeClosed(1, floorCountPerUnit)
                                    .mapToObj(floorId -> {
                                        Building floor = new Building();
                                        floor.setId(generateId(buildingId, unitId, floorId, null));
                                        floor.setName(generateName(buildingId, unitId, floorId, null));
                                        floor.setValue(String.format("%01d", floorId));
                                        floor.setType(3);
                                        floor.setPid(unit.getId());

                                        List<Building> houses = IntStream.rangeClosed(1, houseCountPerFloor)
                                            .mapToObj(houseId -> {
                                                Building house = new Building();
                                                house.setId(generateId(buildingId, unitId, floorId, houseId));
                                                house.setName(generateName(buildingId, unitId, floorId, houseId));
                                                house.setValue(String.format("%02d", floorId)+String.format("%02d", houseId));
                                                house.setType(4);
                                                house.setPid(floor.getId());
                                                return house;
                                            })
                                            .collect(Collectors.toList());

                                        floor.setChildren(houses);
                                        return floor;
                                    })
                                    .collect(Collectors.toList());

                                unit.setChildren(floors);
                                return unit;
                            })
                            .collect(Collectors.toList());

                        building.setChildren(units);
                        return building;
                    }
                )
                .collect(Collectors.toList());
    }

    public static List<Building> generateBuildingHourse(int buildingCount, int unitCountPerBuilding, int floorCountPerUnit, int houseCountPerFloor) {
        List<Building> buildings = generateBuildingList(buildingCount, unitCountPerBuilding, floorCountPerUnit, houseCountPerFloor);
        BuildInfoRes buildInfoRes = new BuildInfoRes();
        //buildings.stream().map(e-> {
        //    String id = e.getId();
        //    Building e1 = e.getType();
        //    return e1;
        //})

        return buildings;
    }

    //private static String generateId(int buildingId, int unitId, int floor, int roomId) {
    //    StringBuilder sb = new StringBuilder();
    //    // 拼接楼栋编号
    //    if (Objects.nonNull(buildingId)) {
    //        sb.append(String.format("%01d", buildingId)).append("-");
    //    }
    //    if (Objects.nonNull(unitId)) {
    //        // 拼接单元编号
    //        sb.append(unitId).append("-");
    //    }
    //    if (Objects.nonNull(floor)) {
    //        // 拼接层数
    //        sb.append(String.format("%02d", floor));
    //    }
    //    if (Objects.nonNull(roomId)) {
    //        // 拼接房间编号
    //        sb.append(String.format("%02d", roomId));
    //    }
    //    return sb.toString();
    //}
}
